/**
 * @author:albert
 */

package com.bkbw.live.battle.business.skill;

import java.util.HashMap;

import com.bkbw.live.common.dataproto.EnumConfigPb.AbilityType;
import com.bkbw.live.battle.business.UnitObject;
import com.bkbw.live.battle.business.ai.AiState;

public class AbilityBase {
	protected String abilityId;
	public String getAbilityId() {
		return abilityId;
	}
	protected AbilityType abilityType;

	public AbilityType getAbilityType() {
		return abilityType;
	}
	protected UnitObject unit;
	
	protected float cooldown = 1.0f;
	protected float tick = 0.0f;
	protected float spellTime = 0.0f;
	protected float spellTick = 0.0f;
	
	public enum AbilityState
	{
		Available,
		Spell,
		Cooldown
	}
	protected AbilityState state;
	
	public AbilityState getState() 
	{
		return state;
	}
	
	public boolean available() 
	{
		return state == AbilityState.Available;
	}
	
	protected float distance;
	protected float distanceSqr;
	
	public AbilityBase(String abilityId, HashMap<String, Object> param)
	{
		this.abilityId = abilityId;
		state = AbilityState.Cooldown;
		// 这里的cooldown必须是float，如果传入的是int等会导致转型错误，因为get可以把Float转为float，而不能直接把Integer转为float
		this.cooldown = (float)param.get("cooldown");
		this.spellTime = (float)param.get("spellTime");
		abilityType = (AbilityType)param.get("abilityType");
		this.distance = (float)param.get("distance");
		distanceSqr = this.distance * this.distance;
	}
	
	public float getDistance()
	{
		return distance;
	}
	
	public float getDistanceSqr()
	{
		return distanceSqr;
	}
	
	public void bind(UnitObject unit)
	{
		this.unit = unit;
	}
	
	public void unbind()
	{
		this.unit = null;
	}
	
	public void update(float dt) 
	{
		if (state == AbilityState.Spell) {
			UnitObject target = this.unit.getTargetEnemy();
			if (target == null || !target.attackable()) {
				state = AbilityState.Available;
				tick = 0;
				spellTick = 0;
				//TODO attack cancel, need broadcast
				return;
			}
			if (spellTick == 0) {
				spellAnim();
			}
			spellTick += dt;
			if (spellTick >= spellTime) {
				tick = 0;
				spellTick = 0;
				state = AbilityState.Cooldown;
				trigger();
			}
		}
		else if (state == AbilityState.Cooldown) {
			tick += dt;
			if (tick >= cooldown) {
				//System.out.println("skill return to available");
				state = AbilityState.Available;
				tick = 0;
				spellTick = 0;
			}
		}
		else if (state == AbilityState.Available){
			
		}
	}
	
	public boolean checkCondition()
	{
		return false;
	}
	
	public void apply()
	{
		
		if (state == AbilityState.Available) {
			state = AbilityState.Spell;
			spellTick = 0;
		}
		else if (state == AbilityState.Spell) {
			
		}
		else if (state == AbilityState.Cooldown) {
			
		}
	}
	
	public void cancel()
	{
		if (state == AbilityState.Available) {
			
		}
		else if (state == AbilityState.Spell) {
			spellTick = 0;
			state = AbilityState.Available;
		}
		else if (state == AbilityState.Cooldown) {
			
		}
	}

	
	public void spellAnim()
	{
		
	}
	
	public void trigger()
	{
		
	}
	
	public boolean isSpelling() {
		if (state == AbilityState.Spell) {
			return true;
		}
		return false;
	}
	
	public boolean isAvailable() {
		if (state == AbilityState.Available) {
			return true;
		}
		return false;
	}
}
